2025-04-09 Progress Report
Wrote some additional SD-card and platform-detection support. The platform is pretty straightforward. I asked in the forums about making this a variable, with no one who knew. I decided it wasn't worth figuring out compared to the other work I have to do, so I went with the "dumb" version.
object *
fn_platform(object *args, object *env)
{
(void) args;
(void) env;
#if defined(PLATFORM_PICOCALC)
const char platformName[] = ":picocalc";
#elif defined(TDECK_PERI_POWERON) /* first t-deck define */
const char platformName[] = ":t-deck";
#elif defined(ARDUINO_TEENSY41)
const char platformName[] = ":teensy41";
#else
const char platformName[] = ":unknown";
#endif
return internlong((char *)platformName);
}
Writing the SD card functions, though, I learned some stuff about how
uLisp works internally. Namely, creating a filename is done with
MakeFilename
.
object *
fn_sd_rename(object *args, object *env)
{
(void) env;
char buffer1[BUFFERSIZE];
char buffer2[BUFFERSIZE];
object *pathFrom = car(args);
if (!stringp(pathFrom)) {
error2("filenames must be strings.");
}
object *pathTo = car(cdr(args));
if (!stringp(pathTo)) {
error2("filenames must be strings.");
}
if (!SD.rename((const char *)MakeFilename(pathFrom, buffer1),
(const char *)MakeFilename(pathTo, buffer2))) {
return nil;
}
return tee;
}
Another useful thing I wanted was a list of all the symbols I'd
defined that I'd lost if I powered off. list-library
will print the
list of symbols in the Lisp Library, but I wanted a list of
symbols. So, I wrote list-library2
. Basically, I just copied the
core of list-library
, then changed it to cons
symbols to a return value:
// (list-library2)
// Return a list of all symbols in the current Lisp library.
object *
fn_listlibrary2(object *args, object *env)
{
(void) args, (void) env;
object *lst = nil;
GlobalStringIndex = 0;
object *line = read(glibrary);
while (line != NULL) {
builtin_t bname = builtin(first(line)->name);
if (bname == DEFUN || bname == DEFVAR) {
lst = cons(second(line), lst);
}
line = read(glibrary);
}
return lst;
}
Added some more code to the LispLibrary
too, including a function to
return all the user-defined symbols. Also, added some functionality
that allows for loading platform-specific code
(e.g. "platform-name.lsp").
(defun user-symbols ()
"(user-symbols)
Returns a list of all the symbols add by a user after boot."
(let ((library (list-library2)))
(remove-if (lambda (sym)
(member sym library))
(globals))))
(defun reset-user-environment ()
"(reset-user-environment)
Removes all user-defined symbols."
(mapcar 'makunbound (user-symbols)))
(defun keyword-string (k)
"(keyword-string k)
Returns the keyword as a string, or nil if the arg isn't a keyword."
(when (keywordp k)
(subseq (string k) 1)))
(defun load-platform ()
"(load-platform)
Load-platform specific code if present, found on the SD card as
platform.lsp (e.g. picocalc.lsp)."
(let ((platform-file (concatenate 'string (keyword-string (platform)) ".lsp")))
(when (sd-exists-p platform-file)
(load platform-file))))
I also asked on the forums about keeping the code for multiple devices synced (specifically, the extensions and Lisp library); the recommendation was to just keep separate trees. I think I'll spend some time investigating uLisp builder.
However, I ran into a snag tonight: it looks like my screen is broken.
I think it happened while I was updating the keyboard firmware, which is unfortunate. Might be relying on the T-Deck more in the near future. It will certainly put a damper on the PicoCalc work.